<?php
class PHZ_Card
{

    /**
     * 获取新生成的牌面信息
     * @banker_index  庄家位置索引，庄家的牌为15个
     * @return array
     */
    public static function __C_Pai( $banker_index ){
        $pai_number = array();
        for( $i = 1 ; $i <= 4 ; $i++ ){
            $index = 1;
            for( $y = 1 ; $y <= 20 ; $y++ ){
                array_push( $pai_number , $index );
                $index++;
            }
        }
        shuffle( $pai_number );shuffle( $pai_number );shuffle( $pai_number );
        //1
        $data_1 = array_slice( $pai_number , 0 , 15 );$data_1 = implode(",",$data_1);
        //2
        $data_2 = array_slice( $pai_number , 15 , 14 );$data_2 = implode(",",$data_2);
        //3
        $data_3 = array_slice( $pai_number , 29 , 14 );$data_3 = implode(",",$data_3);
        //底牌
        $data_5 = array_slice( $pai_number , 43 , 37 );$data_5 = implode(",",$data_5);
        //遍历4个人的牌；不能出现起手2提的情况；出现则重新洗牌(好想法)
        $array  = array( $data_1 , $data_2 , $data_3 );
        foreach ( $array as $key => $value ){
            $data_1_temp = explode(",", $value );
            $data_1_temp_count = array_count_values( $data_1_temp );
            $four = 0;
            foreach ( $data_1_temp_count as $key_1 => $value_1 ){
                if( $value_1 == 4 ){ $four++; }
            }
            if( $four >= 2 ){ return self::__C_Pai( $banker_index ); }
        }
        //根据庄的位置返回牌面信息
        switch ( $banker_index ){
            case 1:
                return array('player_1'=>$data_1,'player_2'=>$data_2,'player_3'=>$data_3,'dipai'=>$data_5);
                break;
            case 2:
                return array('player_1'=>$data_2,'player_2'=>$data_1,'player_3'=>$data_3,'dipai'=>$data_5);
                break;
            case 3:
                return array('player_1'=>$data_3,'player_2'=>$data_2,'player_3'=>$data_1,'dipai'=>$data_5);
                break;
        }
    }

    /**
     * 起手胡牌操作（只针对庄家；且为自摸）;由于没有起始牌；只能依靠自己取自己一个牌来进行判胡操作
     * @info  这里还要考虑是不是打天胡，不打天胡就没有判断的必要了
     * @info  如果可以胡；给庄家下发胡牌通知
     * @info  如果起手提牌数为3的时候，这个时候需要虚拟出一对将来；不然没有将胡不了，因为有提牌
     * @param $room_id
     * @param $zhuangUID
     * @param $card_sp
     */
    public static function __J_Begin_HUpaiCHK( $room_id , $room_info , $zhuangUID  , $tichkCount , $db_connect ){
        //取出该房间对应的当前申请胡牌的用户牌面信息
        $card_info  = $db_connect->select('*')->from('tt_room_card')->where("uid = '". $zhuangUID ."' and jid = '". $room_info['room_js'] ."' and rid= '". $room_id ."' ")->row();
        //取出用户的基本息
        $default_huxi = PHZ_Tools::__get_user_xpAndKanzi_Huxi( $room_id ,$zhuangUID  );
        $card_sp      = explode(",", $card_info['sp'] );
        $temp_cardnumber     = $card_sp[0];
        unset( $card_sp[0] );
        $card_sp  = implode(",", $card_sp );
        if( $tichkCount == 3 ){
            $card_sp = $card_sp . ",1,1";//虚拟出一对小1的将(这对将不能是存在于手牌中的牌)
        }
        $canHu    = PHZ_CanHu::__isCan_Hu_Pai( $default_huxi , $card_sp , $temp_cardnumber , $temp_cardnumber , $room_info );//进行胡牌判定操作
        if( $canHu['canHu'] == true ){
            //获取我的基本位置
            $my_index = PHZ_User::__get_user_Room_Index( $room_info , $zhuangUID );
            //更新自己is_hu状态
            $db_connect->update('tt_room')->cols(array('p' . ($my_index) . '_is_hu' => 1))->where('room_id=' . $room_id)->query();//更新当前房间当前位置用户的胡状态
            //发送胡牌信息
            $temp = array();
            $temp['pl']          = 30;//自摸胡牌可按钮通知
            $temp['card_number'] = $temp_cardnumber;//天胡的牌号，就刚刚随便取的那张就行了
            PHZ_Log::__send_user_log_IN_Single( $room_info , $zhuangUID , $zhuangUID , $temp  , $db_connect );
        }
    }

    /**
     * 起手提牌检查
     * @param $card_temp
     * @param $room_info
     * @param $js
     * @param $db_connect
     */
    public static function _J_Begin_After_TICHK( $card_temp , $room_info , $js , $db_connect ){
        $room_id = $room_info['room_id'];
        #.欲清除的提牌数组
        $tipai_delete = array();
        #.进行遍历查找提牌操作
        foreach( $card_temp as $key_1 => $value_1 ){
            #.进行手牌中是否有4个相同的检查
            $sp = $value_1['sp'];
            $sp = explode(",", $sp );
            $sp_card_count = array_count_values( $sp );
            foreach( $sp_card_count as $key_2 => $value_2 ){
                if( $value_2 == 4 ){//找到提
                    //插入提牌数据
                    self::__addTipai( $room_id , $room_info['room_js'] , $value_1['uid'] , (int)$key_2 , $db_connect );
                    //增加起手提牌息数
                    PHZ_SuanXi::__xi( $room_info , $value_1['uid'] , "qs_tipai" , (int)$key_2 , $db_connect );
                    //给自己发送提的消息，里面包含被提走的牌号；给其他三个人发送有人提的消息；但是不能显示提走的牌
                    foreach( $room_info as $key_3 => $value_3 ){
                        if( strstr( $key_3 , 'room_player_') != false && $value_3 != 0 ){
                            $data = array();
                            $data['log_rid']     = $room_id;
                            $data['log_jid']     = $room_info['room_js'];
                            $data['log_uid']     = $value_1['uid'];//提牌人
                            $data['log_to_uid']  = $value_3;//给谁发送
                            $data['log_md']      = 15;
                            $temp = array();
                            $temp['pl']          = 10;//10为有用户进行了起手提牌操作
                            if( $value_3 == $value_1['uid'] ){
                                $temp['card_number'] = (int)$key_2;//被提的这个牌的号码（仅自己可见）
                            }else{
                                $temp['card_number'] = 0;//非提牌人看不到提的牌（这里是否要做成可选项？？？待解....................................）
                            }
                            $data['log_data']    = json_encode( $temp );
                            $db_connect->insert( PHZ_Log::__gTn( $room_id ) )->cols( $data )->query();
                            PHZ_Card::__update_MAX_HeaderID( $room_info , $value_3 , $db_connect );//更新用户的当前最大可执行ID
                        }
                    }
                    //清除提牌人自身的手牌信息
                    $tipai_delete[$value_1['uid']]['sp']        = $sp;//手牌
                    $tipai_delete[$value_1['uid']]['pai_hao'][] = $key_2;//将要提的牌置入到数组中
                }
            }
        }
        //清除提牌人手中的牌
        foreach( $tipai_delete as $key => $value ){
            //下牌临时
            $xp = "";
            //手牌清楚
            foreach( $value['pai_hao'] as $key_2 => $value_2 ){
                foreach( $value['sp'] as $key_3 => $value_3 ){
                    if( $value_2 == $value_3 ){
                        unset( $value['sp'][$key_3] );
                        $xp = $xp . $value_3 . "_";
                    }
                }
                $xp = substr($xp,0,-1) . ",";
            }
            //起手几提？ - 事实上被限制了；顶多1提
            $ti_pao = 0;
            $mianda = 0;
            if( count($value['pai_hao']) == 1 ){$ti_pao = 1;$mianda =0;}//起手1提，进子免打0次
            if( count($value['pai_hao']) == 2 ){$ti_pao = 2;$mianda =1;}//起手2提，进子免打1次
            if( count($value['pai_hao']) == 3 ){$ti_pao = 3;$mianda =2;}//起手3提，进子免打2次
            if( count($value['pai_hao']) == 4 ){$ti_pao = 4;$mianda =3;}//起手3提，进子免打3次
            //数据更新
            $db_connect->update('tt_room_card')->cols(array('mianda'=>$mianda,'ti_pao'=>$ti_pao,'xp'=> $xp ,'sp'=> implode(",",$value['sp'])  ))->where('uid = '. $key .' and jid = '. $js .' and rid=' . $room_info['room_id'] )->query();
        }
        //返回起手提牌数(这里的返回没什么用，就0随便好了)
        return 0;
    }

    /**
     * 删除某条card_info信息中某个用户的一个手牌,同时增加一个下牌信息
     * @param $card_info     房间信息列表
     * @param $db_connect    数据链接
     */
    public static function __delete_user_SP_AND_Add_BP( $card_info , $user_id , $card_number ,  $db_connect ){
        foreach ( $card_info as $key => $value ){
            if( $value['uid'] == $user_id ){
                $my_card_info = $value;
                break;
            }
        }
        $my_sp  = explode(",",$my_card_info['sp']);
        foreach( $my_sp as $key => $value ){
            if( $value == $card_number ){
                unset( $my_sp[$key] );
                break;
            }
        }
        $my_sp   = implode(",", $my_sp );
        $my_bp   = $my_card_info['bp'] . $card_number  . ",";
        $db_connect->update('tt_room_card')->cols(array('sp'=> $my_sp , 'bp' => $my_bp ))->where('id=' . $my_card_info['id'] )->query();
        return true;
    }

    /**
     * 获取下一张底牌信息
     * @param $room_info
     * @param $db_connect
     * @return mixed
     */
    public static function __get_next_card_number( $room_info , $db_connect ){
        $card_info        = $db_connect->select('*')->from('tt_room_card')->where('jid = '. $room_info['room_js'] .' and rid=' . $room_info['room_id'] )->row();//取出随便那个人的底牌信息
        $dipai            = $card_info['dp'];
        $dipai            = explode(",",$dipai);
        $next_card_number = $dipai[0];unset($dipai[0]);
        $db_connect->update('tt_room_card')->cols(array('dp'=> implode(",",$dipai)  ))->where('jid = '. $room_info['room_js'] .' and rid=' . $room_info['room_id'] )->query();
        return $next_card_number;
    }

    /**
     * 用户取消吃，碰，胡后的牌号记录操作
     * @param $room_info
     * @param $user_id
     * @param $card_number
     * @param $pass_type
     */
    public static function __set_UserPass_CHI_PENG_HU( $room_info , $user_id , $card_number  , $db_connect ){
        $where             = "uid = '". $user_id ."' and rid = '". $room_info['room_id'] ."' and jid = '". $room_info['room_js'] ."'";
        $user_card_info    = $db_connect->select('*')->from('tt_room_card')->where( $where )->row();
        $user_index        = PHZ_User::__get_user_Room_Index( $room_info , $user_id );
        if( $room_info['p'. $user_index .'_is_chi'] == 1 ){
            $pass_chi  = $user_card_info['pass_chi'] . $card_number . ",";
            $db_connect->update('tt_room_card')->cols(array('pass_chi'=> $pass_chi  ))->where('id = '. $user_card_info['id'] )->query();
        }
        if( $room_info['p'. $user_index .'_is_peng'] == 1 ){
            $pass_peng  = $user_card_info['pass_peng'] . $card_number . ",";
            $db_connect->update('tt_room_card')->cols(array('pass_peng'=> $pass_peng  ))->where('id = '. $user_card_info['id'] )->query();
        }
        if( $room_info['p'. $user_index .'_is_hu'] == 1 ){
            $pass_hu  = $user_card_info['pass_hu'] . $card_number . ",";
            $db_connect->update('tt_room_card')->cols(array('pass_hu'=> $pass_hu  ))->where('id = '. $user_card_info['id'] )->query();
        }
        return true;
    }

    /**
     * 用户如果打出了一个牌；那这个牌应该直接存在pass_chi跟pass_碰当中
     * @param $room_info
     * @param $user_id
     * @param $card_number
     * @param $db_connect
     */
    public static function __set_UserInputPai_PassLOG( $room_info , $user_id , $card_number  , $db_connect ){
        $where             = "uid = '". $user_id ."' and rid = '". $room_info['room_id'] ."' and jid = '". $room_info['room_js'] ."'";
        $user_card_info    = $db_connect->select('*')->from('tt_room_card')->where( $where )->row();
        $pass_chi   = $user_card_info['pass_chi']  . $card_number . ",";
        $pass_peng  = $user_card_info['pass_peng'] . $card_number . ",";
        $db_connect->update('tt_room_card')->cols(array('pass_chi'=> $pass_chi , 'pass_peng' => $pass_peng  ))->where('id = '. $user_card_info['id'] )->query();
        return true;
    }

    /**
     * 用户在执行了吃，碰，畏三种操作后；如果手中还有进子免打的权限；则返回一次true；并去除一次免打权利
     * @param $room_info     房间信息
     * @param $user_id       用户ID
     * @param $db_connect    数据链接标识
     */
    public static function __get_User_TIPAO_Free_to_Play( $room_info , $user_id , $db_connect ){
        $where             = "uid = '". $user_id ."' and rid = '". $room_info['room_id'] ."' and jid = '". $room_info['room_js'] ."'";
        $user_card_info    = $db_connect->select('*')->from('tt_room_card')->where( $where )->row();
        if( $user_card_info['mianda'] <= 0 ){
            return false;
        }
        $del_mianda = $user_card_info['mianda'] - 1;
        $db_connect->update('tt_room_card')->cols(array('mianda'=> $del_mianda  ))->where('id = '. $user_card_info['id'] )->query();
        return true;
    }


    /**
     * 判断一手牌是否为碰胡
     * @param $cards
     * @info (碰碰胡判断条件：手里的所有牌均为4个或者3个或者2个相同的；如果出现了4个相同的，那么必须会有一对且只能有一对相同的;如果没有4个，那么其他的必须全部是3个)
     */
    public static function __Cards_ispengHU( $cards ){
        $card_count = array_count_values( $cards );
        $count_1 = 0;//1个牌出现的次数
        $count_2 = 0;//2张牌出现的次数
        foreach ( $card_count as $key => $value ){
            if( $value == 1 ){$count_1++;}
            if( $value == 2 ){$count_2++;}
        }
        //如果有单牌出现，则肯定不是
        if( $count_1 >= 1 ){ return false; }
        //如果2张相同的牌出现了2次，那肯定也不是；因为就算是跑起胡，也顶多只能有1墩2张一样的
        if( $count_2 >= 2 ){return false; }
        return true;
    }

    /**
     * 更新用户的最新最大的log心跳ID
     * @param $room_info
     * @param $user_id
     * @param $db_connect
     */
    public static function __update_MAX_HeaderID( $room_info , $user_id , $db_connect ){
        //查找用户当前的最大执行ID
        $where     = "log_to_uid = '". $user_id ."' and log_rid = '". $room_info['room_id'] ."' and log_jid = '". $room_info['room_js'] ."'";
        $log_info  = $db_connect->row("select * from ".PHZ_Log::__gTn( $room_info['room_id'] )." where " . $where . " order by id desc limit 1");
        //更新当前的最大执行ID
        $where     = "uid = '". $user_id ."' and rid = '". $room_info['room_id'] ."' and jid = '". $room_info['room_js'] ."'";
        $db_connect->update('tt_room_card')->cols(array( 'max_id' => $log_info['id']  ))->where( $where )->query();
        //把当前用户的可执行数据存入缓存中
        PHZ_Memcache::__set_userAllLog_DATA( $room_info['room_id'] , $room_info['room_js'] , $user_id );
        return true;
    }

    /**
     * 获取一个用户他当前的最大执行ID
     * @param $room_info
     * @param $user_id
     * @param $db_connect
     * @return int
     */
    public static function __get_MAX_HeaderID( $room_info , $user_id , $db_connect ){
        $where     = "uid = '". $user_id ."' and rid = '". $room_info['room_id'] ."' and jid = '". $room_info['room_js'] ."'";
        $max_info = $db_connect->select('*')->from('tt_room_card')->where( $where )->row();
        return (int)$max_info['max_id'];
    }

    /**
     * 通过房间信息获取当前局数所有信息
     * @param $room_info
     * @param $user_id
     * @param $db_connect
     */
    public static function __get_USER_RoomSignle_Info( $room_info , $db_connect ){
        $where  = "rid = '". $room_info['room_id'] ."' and jid = '". $room_info['room_js'] ."'";
        return $db_connect->select('*')->from('tt_room_card')->where( $where )->query();
    }

    /**
     * 增加一个打牌记录；（这里就是纯粹的记录打出过的牌）
     * @param $room_info
     * @param $card_info
     * @param $user_id
     * @param $card_number
    * @param $db_connect
    * @return mixed
    */
    public static function __InsertPut_LogCard( $room_info ,  $user_id , $card_number ,  $db_connect ){
        $where     = "uid = '". $user_id ."' and rid = '". $room_info['room_id'] ."' and jid = '". $room_info['room_js'] ."'";
        $card_info = $db_connect->select('*')->from('tt_room_card')->where( $where )->row();
        $put_log   = $card_info['put_log'] . $card_number . ",";
        return $db_connect->update('tt_room_card')->cols( array( 'put_log' => $put_log  ) )->where( $where )->query();
    }


    /** 添加一个用户的提牌信息（注意是提牌；不是跑牌）
     * @param $room_id
     * @param $room_js
     * @param $user_id
     * @param $card_numberr
     * @param $db_connect
     */
    public static function __addTipai( $room_id , $room_js , $user_id , $card_number ,$db_connect  ){
        $where     = "uid = '". $user_id ."' and rid = '". $room_id ."' and jid = '". $room_js ."'";
        $card_info = $db_connect->select('*')->from('tt_room_card')->where( $where )->row();
        $card_ti   = $card_info['card_ti'] . $card_number . ",";
        return $db_connect->update('tt_room_card')->cols( array( 'card_ti' => $card_ti  ) )->where( $where )->query();
    }

    /**
     * 假如需要吃或者碰的时候，检测手中还有几个牌，低于2个不允许做操作了；如果可以胡因为就是现胡按钮，否则不能胡，吃碰也没有意义
     * @param $user_id
     * @param $sp
     * @param $card
     * @param $mode
     * @param $db_connect
     * @return bool
     */
    public static function __chkCHiPeng_Last( $sp ){
        $handSp = explode(",", $sp );
        #.如果当前手牌中存在的牌数量大于等于3个，那么就允许吃；正常是不会出现3个的情况。要么4个要么2个
        $find = 0;
        foreach ( $handSp as $key => $value ){
            if( (int)$value >= 1 && (int)$value <= 20 ){ $find++; }
        }
        if( $find >= 3 ) {
            return true;
        }
        return false;
    }

    /**
     * 将card_info进行按照当前出牌人或者摸牌人进行重新顺序整理操作
     * @param $c
     * @param $user_id
     * @return array|bool
     */
    public static function __cardInfoUserSort( $c , $user_id ){
        $c = array_values( $c );//重置下标索引
        $new_card_info = false;
        if( $c[0]['uid'] == $user_id ){
            $new_card_info = array( $c[0],$c[1],$c[2] );
        }
        if( $c[1]['uid'] == $user_id ){
            $new_card_info = array( $c[1],$c[2],$c[0] );
        }
        if( $c[2]['uid'] == $user_id ){
            $new_card_info = array( $c[2],$c[0],$c[1] );
        }
        if( $new_card_info === false ){
            return $c;
        }
        return $new_card_info;
    }

    /**
     * 作用：跑牌胡的判断的时候，需要用一张临时牌；这个临时牌不能是已经存在手里的三张；否则就出现了拿三张牌去做坎子的情况了
     * @param $shou_pai
     * @return array
     */
    public static function __cardSpGETPaoSP__AND_TEMP_CARD_NUMBER( $shou_pai ){
        if( $shou_pai == "" || $shou_pai == "," ){
            return array( "" , 0 , 0 );
        }
        $shou_pai  = explode("," , $shou_pai);
        $add_xi    = 0;//BUG:如果去掉了牌，那么你得把息加上才对
        if( count( $shou_pai ) <= 0 ){return array( "" , 0 , 0 );}
        $shouPai_count = array_count_values( $shou_pai );
        foreach ( $shouPai_count as $key => $value ){
            if( $value == 3 ){
                if( $key <= 10 ) {
                    $add_xi = $add_xi + 3;//小字+3
                }else{
                    $add_xi = $add_xi + 6;//大字+6
                }
                foreach ( $shou_pai as $key_1 => $value_1 ){
                    if( $value_1 == $key ){
                        unset( $shou_pai[$key_1] );
                    }
                }
            }
        }
        $shou_pai = array_values( $shou_pai );
        if( count( $shou_pai ) <= 0 ){return array( "" , 0 , 0 );}
        $temp_cardnumber = $shou_pai[0];
        unset( $shou_pai[0] );
        $shou_pai     = implode(",",$shou_pai);
        return array( $shou_pai , $temp_cardnumber , $add_xi );
    }

}













